﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace Kinect_Dance
{

    class KinectManager
    {
        public enum KinectConnectedState
        {
            Connected,
            Disconnected,
            Error,
            NotPower
        }

        // Variables
        private static KinectManager instance = null;
        KinectSensor mSensor;
        String mConnectedStatus;
        private KinectConnectedState mState;
        private Skeleton mSkeleton;
        private Skeleton[] mSkeletonData;
        // Event
        public event EventHandler kinect_skeletonReady = delegate { };
        public event EventHandler kinect_allFramesReady = delegate { };
        public event EventHandler kinect_colorFramesReady = delegate { };
        public event EventHandler kinect_depthImageReady = delegate { };


        public KinectConnectedState ConnectedState
        {
            get {   return mState;  }
            set {   mState = value; }
        }

        public static KinectManager getInstance()
        {
            if (instance == null)
            {
                instance = new KinectManager();
            }
            return instance;
        }

        public KinectManager()
        {
            initKinect();
        }

        private void initKinect()
        {
            KinectSensor.KinectSensors.StatusChanged += new EventHandler<StatusChangedEventArgs>(KinectSensors_StatusChanged);
            mSensor = KinectSensor.KinectSensors[0];
           
            mSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinect_allFramesReady);
            mSensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinect_colorFramesReady);
            mSensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinect_skeletonReady);
            mSensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(kinect_depthImageReady);
        }

        public void enableColorStream(ColorImageFormat colorImageFormat)
        {
            mSensor.ColorStream.Enable(colorImageFormat);
        }

        public void disableColorStream()
        {
            mSensor.ColorStream.Disable();
        }

        public void enableDepthStream(DepthImageFormat format)
        {
            mSensor.DepthStream.Enable(format);
        }

        public void disableDepthStream()
        {
            mSensor.DepthStream.Disable();
        }

        public void enableSkeletonStream()
        {
            mSensor.SkeletonStream.Enable();
        }

        public void disableSkeletonStream()
        {
            mSensor.SkeletonStream.Disable();
        }

        public void startKinect()
        {
            mSensor.Start();
        }

        public void stopKinect()
        {
            mSensor.Stop();
        }

        private void DiscoverKinectSensor()
        {
            mConnectedStatus = "";
            foreach (KinectSensor sensor in KinectSensor.KinectSensors)
            {
                /// Found one, set our sensor to this
                mSensor = sensor;
                break;
            }

            if (this.mSensor == null)
            {
                mConnectedStatus = "Found none Kinect Sensors connected to USB";
            }

            switch (mSensor.Status)
            {
                case KinectStatus.Connected:
                    {
                        mConnectedStatus = "Status: Connected";
                        mState = KinectConnectedState.Connected;
                        break;
                    }
                case KinectStatus.Disconnected:
                    {
                        mConnectedStatus = "Status: Disconnected";
                        mState = KinectConnectedState.Disconnected;
                        break;
                    }
                case KinectStatus.NotPowered:
                    {
                        mConnectedStatus = "Status: Connect the power";
                        mState = KinectConnectedState.NotPower;
                        break;
                    }
                default:
                    {
                        mConnectedStatus = "Status: Error";
                        mState = KinectConnectedState.Error;
                        break;
                    }
            }

            // Init the found and connected device
            if (mSensor.Status == KinectStatus.Connected)
            {
                initKinect();
            }
        }


        void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            if (this.mSensor == e.Sensor)
            {
                if (e.Status == KinectStatus.Disconnected ||
                    e.Status == KinectStatus.NotPowered)
                {
                    this.mSensor = null;
                    this.DiscoverKinectSensor();
                }
            }
        }
    }
}
